import chartOp from '@/common/chart-option.js';
import { $demoi18n } from '@/utils/lang';
import {
  clone, convertValue,
  getColor, getEchartXYAxisType,
  getSerieColor, getThemeColors, isNum,
  numFormat,
  setExtraConfig,
  xssFilter,
  mergeColorBoard,
} from '@/utils/util';
import optionList from './chart-option.json';
import _colorBoard from './color_board.js';
const colorBoard = mergeColorBoard(_colorBoard);
const tooltip = {
  backgroundColor: '',
  dataLength: '',
  seriesNameColor: '',
  componentStyle: '',
};
const chartOption = null;

function getValueNum(str) {
  const ret = `${str}`;
  if (ret.indexOf(',') > -1) {
    return Number(ret.replace(/,/gm, ''));
  }
  if (!isNaN(Number(str))) {
    if (str === null || str === undefined) {
      return null;
    } else if (str === '') {
      return NaN;
    } else {
      return Number(str);
    }
  }
  return str;
}

function getThresholdColor(_color, threshold, params, valueAxis) {
  let color = _color;
  threshold.map(child => {
    if (child.field && child.field !== params.seriesName) {
      return color;
    } else {
      const index = valueAxis === 'y' ? 1 : 0;
      params.data[index] !== null &&
        getValueNum(params.data[index]) >= Number(child.min) &&
        getValueNum(params.data[index]) < Number(child.max) ?
        (color = child.color) :
        null;
      return color;
    }
  });
  return color;
}

export const getValueAxis = property => {
  const { echart } = property;
  if (!echart || !echart.xAxis || !echart.yAxis) {
    return '';
  }
  const xType = echart.xAxis.type;
  const yType = echart.yAxis.type;
  if (xType === 'value') {
    return 'x';
  }
  if (yType === 'value') {
    return 'y';
  }
  return '';
};

/**
 * 设置图表数据 series legend等
 * @param {*} option 图表option
 * @param {*} data 图表数据
 * @param {*} property 配置页面中属性面板中的参数
 */
function setChartData(option, data, property) {
  const { xAxisData, seriesData } = data;
  const { componentStyle, legend, color, threshold, isThreshold } = property;
  option.xAxis.data = xAxisData;
  const colors = getThemeColors(color, colorBoard[componentStyle].colorGroup);
  const { isSingleSerieMultiColor } = property;
  const valueAxis = getValueAxis(property);

  const colorGroupLength = colors.length;

  seriesData.forEach((item, index) => {
    const serie = {
      type: 'bar',
      name: item.name,
      data: item.data,
    };

    serie.itemStyle = {};
    serie._legendColor = '';

    // 单系列多颜色
    if (isSingleSerieMultiColor && seriesData.length === 1) {
      serie.itemStyle = {
        color: function(params) {
          let _color;
          if (typeof color === 'string') {
            _color = colors[params.dataIndex % colorGroupLength];
          } else {
            _color = getColor(color, item.name);
          }
          _color = getSerieColor(_color);

          if (isThreshold) {
            _color = getThresholdColor(_color, threshold, params, valueAxis);
          }
          return _color;
        },
      };
    } else {
      if (typeof color === 'string') {
        serie.itemStyle.color = getSerieColor(colors[index % colorGroupLength]);
      } else {
        serie.itemStyle.color = getSerieColor(getColor(color, item.name));
      }
      const retColor = serie.itemStyle.color;
      const hasThresholdSerie = threshold.some(n => n.field === serie.name);
      if (isThreshold && hasThresholdSerie) {
        serie._legendColor = retColor;
        serie.itemStyle.color = function(params) {
          const tColor = getThresholdColor(retColor, threshold, params, valueAxis);
          return tColor;
        };
      }
    }

    const legendDataItem = {
      name: item.name,
    };
    if (serie._legendColor) {
      legendDataItem.itemStyle = { color: serie._legendColor };
    }
    item.name && option.legend.data.push(legendDataItem);
    option.series.push(serie);
  });

  // 有无图例
  if (!legend) {
    option.legend.show = false;
  }
}

/**
 * 有yAxisName时重新调整option 样式
 * @param {*} option 图表option
 * @param {*} property 配置页面中属性面板中的参数
 */
function setYAxisName(option, property) {
  const { yAxisName, componentStyle } = property;
  if (!yAxisName) {
    return;
  }
  option.yAxis = {
    ...option.yAxis,
    name: yAxisName,
    nameTextStyle: {
      color: colorBoard[componentStyle].yAxis.axisLabel.textStyle.color,
    },
  };
}

// 设置参考线
function setMarkLine(option, property, configData) {
  if (configData.hasMarkLine && configData.markLineValue) {
    const flag = isNum(configData.markLineValue);
    if (!flag) {
      return;
    }
    const { componentStyle } = property;
    option.series[0].markLine = {
      silent: true,
      data: [
        {
          name: $demoi18n('word.referenceValue'),
          yAxis: configData.markLineValue,
        },
      ],
      symbol: ['none', 'none'],
      label: {
        show: false,
      },
      emphasis: {
        label: false,
      },
      lineStyle: {
        width: 2,
        opacity: 1,
        color: colorBoard[componentStyle].markLine.lineStyle.color,
        type: 'dotted',
      },
    };
  }
}

// 设置堆叠状态
function setStackStatus(option, property) {
  const { arrangement } = property;
  if (arrangement && arrangement === 'stack') {
    const stackName = 'chart-stack';
    option.series.forEach(item => {
      item.stack = stackName;
    });
  }
}

/**
 * 自定义图表提示框
 * @param {*} params  echart自带参数
 */
function formateTooltip(params) {
  if (!chartOp.isOrgTooltipVisible()) {
    return '';
  }

  const { seriesNameColor } = tooltip;
  let formatStr = '<div class=\'tooltip_bar\'>';
  params.forEach((item, index) => {
    xssFilter(item, ['axisValue', 'seriesName', 'value']);
    let v0 = item.value[0];
    let v1 = item.value[1];
    if (window.visualComp._tranXYAxis) {
      v0 = item.value[1];
      v1 = item.value[0];
    }

    if (index === 0) {
      formatStr += `<span>${v0}</span><br/>`;
    }
    if (item.color && item.color.colorStops) {
      const { color } = item.color.colorStops[0];
      if (item.seriesName) {
        formatStr +=
          '<span style=\'display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;' +
          `background-color:${color};'></span><span style='color:${seriesNameColor}'> ${
            item.seriesName
          }:</span> ${numFormat(v1, true)}`;
      } else {
        formatStr +=
          '<span style=\'display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;' +
          `background-color:${color};'></span><span style='color:${seriesNameColor}'> </span> 
          ${numFormat(v1, true)}`;
      }
    } else {
      if (item.seriesName) {
        formatStr += `${item.marker}<span style='color:${seriesNameColor}'>${item.seriesName}:</span> 
        ${numFormat(v1, true)}`;
      } else {
        formatStr += `${item.marker}<span style='color:${seriesNameColor}'></span> ${numFormat(v1, true)}`;
      }
    }
    if (index !== params.length) {
      formatStr += '<br/>';
    }
  });
  formatStr += '<div/>';

  return formatStr;
}

function convertDataHorizontal(data, configData, valueAxis) {
  if (!data.length) {
    return false;
  }

  const yCount = configData.tableData.length - 1;
  const _x = valueAxis === 'y' ? 'x' : 'y1';

  const seriesData = [];
  const dataObj = {};

  let xAxisData = data.map(n => n[_x]);
  xAxisData = Array.from(new Set(xAxisData));

  // 初始化数组
  for (let i = 0; i < yCount; i++) {
    const row = configData.tableData[i + 1];
    dataObj[`y${i}Data`] = {
      data: [],
      legendName: row?.legendName || `Serie_${i + 1}`,
      flag: false,
    };
  }

  for (let index = 0; index < xAxisData.length; index++) {
    const x = xAxisData[index];
    const tempItem = data.find(d => d[_x] === x);

    // 填充数据
    for (let i = 0; i < yCount; i++) {
      let val;
      if (_x === 'x') {
        val = tempItem[`y${i + 1}`];
        dataObj[`y${i}Data`].data.push([x, val, JSON.stringify(tempItem)]);
      } else {
        val = tempItem['x'];
        dataObj[`y${i}Data`].data.push([val, x, JSON.stringify(tempItem)]);
      }
    }
  }
  for (let i = 0; i < yCount; i++) {
    seriesData.push({
      yAxisIndex: 0,
      type: 'bar',
      name: dataObj[`y${i}Data`].legendName,
      data: dataObj[`y${i}Data`].data,
    });
  }

  if (seriesData.length === 0) {
    return null;
  }

  return {
    xAxisData,
    seriesData,
  };
}

function convertDataLongitudinal(data, configData, valueAxis) {
  const _x = valueAxis === 'y' ? 'x' : 'y';
  if (data.length) {
    const seriesData = [];
    let xAxisData = [];
    const { seriesKey } = chartOp.getXAxisKeyAndSeriesKey(data, valueAxis);

    if (seriesKey.length) {
      seriesKey.forEach(s => {
        const serieData = data
          .filter(n => n.s === s)
          .map(n => [n.x, n.y, JSON.stringify(n)]);
        seriesData.push({
          name: s,
          data: serieData,
        });
      });
    } else {
      const serieData = data.map(n => [n.x, n.y, JSON.stringify(n)]);
      seriesData.push({
        name: '',
        data: serieData,
      });
    }

    xAxisData = data.map(n => n[_x]);
    xAxisData = Array.from(new Set(xAxisData));

    return {
      xAxisData,
      seriesData,
    };
  } else {
    return null;
  }
}

// 根据y轴标签判断并修正y轴类型（category,time,value）
function fixYAxisType(option) {
  let yArr = [];
  option.series.forEach(n => {
    yArr = [...yArr, ...n.data];
  });
  const type = getEchartXYAxisType(yArr);
  option.yAxis.type = type;
}

/**
 * 将接口数据转换为echart方便使用的数据
 * @param {*} data 接口数据
 */
export const convertData = function(data, configData, valueAxis) {
  const _valueAxis = valueAxis ? valueAxis : 'y';
  if (configData.dataMappingType === 'horizontalData') {
    return convertDataHorizontal(data, configData, _valueAxis);
  } else {
    return convertDataLongitudinal(data, configData, _valueAxis);
  }
};

export const setChartOption = (data, property, configData, extraConfig = {}) => {
  const { xAxisName = '', componentStyle, barWidth = 10 } = property;
  const { originTooltipSetting } = property.tooltip || {};
  tooltip.backgroundColor =
    (originTooltipSetting && originTooltipSetting.background) || colorBoard[componentStyle].tooltip.backgroundColor;
  tooltip.dataLength = data.xAxisData.length;
  tooltip.componentStyle = componentStyle;
  tooltip.seriesNameColor = colorBoard[componentStyle].tooltip.seriesNameColor;
  const { animation = true } = extraConfig;
  const vars = {
    animation,
    componentStyle,
    colorBoard,
    tooltip,
    formateTooltip,
    xAxisName,
    barWidth: convertValue(barWidth),
    xLabelRotate: property.xLabelRotate || 0,
  };
  let option = clone(optionList);
  option = chartOp.parseJsonOption(option, vars);
  option.legend.right = 50;

  chartOp.setDataZoom('uniaxial-bar', { option, data, property, colorBoard });
  setChartData(option, data, property);
  chartOp.setYAxisName('uniaxial-bar', { option, property, colorBoard });
  chartOp.setMarkLine('uniaxial-bar', { option, property, configData, colorBoard });
  setStackStatus(option, property);

  const extraConfigKeyLength = Object.keys(extraConfig).length;
  if (extraConfigKeyLength) {
    setExtraConfig(option, extraConfig);
  }

  // 现网环境不知道为何会显示数据标签，兼容处理把数据标签显示关闭
  const label = property.echart && property.echart.series && property.echart.series.label;
  if (label && label.show) {
    label.show = false;
  }

  // 附加公共配置
  option = chartOp.mergeOption(option, property);

  return option;
};
